/*
**
**  My array solutions
**
*/

#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>

#include "arraylib.h"
#include "message.h"

/*
**  管理整型数组的结构.
**  @elem pBase:数组的起始地址;
**  @elem cnt:有效元素个数,起始值为1;
**  @elem length:数组总长度,起始值为1;
*/
/*
typedef struct _int_array
{
    int *pBase; 
    int cnt;
    int length;
} INT_ARRAY;
*/
/*
**  分配整型数组需要的内存空间并初始化.
**  @param p_iArr:管理整型数组的结构;
**  @param iLength:整型数组的长度(元素个数);
**  @ret   success:true;failed:false;
*/
bool init_int_array(INT_ARRAY *p_iArr, int iLength)
{
    p_iArr->pBase = (int *) malloc(sizeof(int) * iLength);
    if(NULL == p_iArr->pBase)
    {
        printf("%s\n", MSG_ERR_1);
        return false;
    }
    p_iArr->cnt    = 0;
    p_iArr->length = iLength;
    return true;
}

/*
**  销毁数组,释放回收内存空间.
**  @param p_iArr:管理整型数组的结构;
**  @ret   void;
*/
void destroy_int_array(INT_ARRAY *p_iArr)
{
    free(p_iArr);
    p_iArr = NULL;
    return;
}

/*
**  取得当前数组中元素个数.
**  @param p_iArr:管理整型数组的结构;
**  @ret   数组中的元素个数;
*/
int get_elem_number(INT_ARRAY *p_iArr)
{
    return p_iArr->cnt;
}

/*
**  打印元素.
**  @param p_iArr:管理整型数组的结构;
*/
void show_elem(INT_ARRAY *p_iArr)
{
    for(int i=0; i<p_iArr->cnt; i++)
    {
        printf("%d ", p_iArr->pBase[i]);
    }
    printf("\n");
}

/*
**  追加元素到数组中.
**  @param p_iArr:管理整型数组的结构;
**  @param iElem:追加的元素值;
**  @ret   追加成功:true;追加失败:false;
*/
bool add_elem_to_array(INT_ARRAY *p_iArr, int iElem)
{
    // 数组判满
    if(int_array_isFull(p_iArr))
    {
        return false;
    }
    p_iArr->pBase[p_iArr->cnt] = iElem;
    p_iArr->cnt++;
    return true;
}

/*
**  删除数组中的最后一个有效元素.
**  @param p_iArr:管理整型数组的结构;
**  @ret   删除成功:true;删除失败:false;
*/
bool delete_elem_from_array(INT_ARRAY *p_iArr)
{
    // 判空
    if(int_array_isEmpty(p_iArr))
    {
        return false;
    }
    p_iArr->cnt--;
    return true;
}

/*
**  修改数组中的一个有效元素.
**  @param p_iArr:管理整型数组的结构;
**  @param iPos:修改第n个元素,n从1开始;
**  @param iVal:修改元素iPos位置的元素值为iVal;
**  @ret   修改成功:true;修改失败:false;
*/
bool replace_elem_at(INT_ARRAY *p_iArr, int iPos, int iVal)
{
    //位置有效性判断
    if(!valid_index(p_iArr, iPos))
    {
        printf("%s", MSG_ERR_4);
        return false;
    }
    p_iArr->pBase[iPos-1] = iVal;
    return true;
}

/*
**  插入一个有效元素到数组中.
**  @param p_iArr:管理整型数组的结构;
**  @param iPos:第n个位置插入元素,n从1开始;
**  @param iVal:插入元素的值为iVal;
**  @ret   插入成功:true;插入失败:false;
*/
bool insert_elem_at(INT_ARRAY *p_iArr, int iPos, int iVal)
{

    // 判满
    if(int_array_isFull(p_iArr))
    {
        return false;
    }
    //位置有效性判断
    if(!valid_index(p_iArr, iPos))
    {
        printf("%s", MSG_ERR_5);
        return false;
    }
    //插入位置开始的元素后移
    for(int i=iPos-1; i<p_iArr->cnt; i++)
    {
        p_iArr->pBase[i+1] = p_iArr->pBase[i];
    }
    p_iArr->pBase[iPos-1] = iVal;
    p_iArr->cnt++;
    return true;
}

/*
**  对数组中有效元素排序.
**  @param p_iArr:管理整型数组的结构;
**  @param iOrd:0:ascending order;1:descending order;
**  @ret   成功:true;失败:false;
*/
bool sort_int_array(INT_ARRAY *p_iArr, int iOrd)
{
    int temp;
    switch (iOrd)  //...重复代码..算了不改了..
    {
        case 0:
            for(int i=0; i<p_iArr->cnt-1; i++)
            {
                for(int j=i+1; j<p_iArr->cnt; j++)
                {
                    if(p_iArr->pBase[i] > p_iArr->pBase[j])
                    {
                        temp = p_iArr->pBase[i];
                        p_iArr->pBase[i] = p_iArr->pBase[j];
                        p_iArr->pBase[j] = temp;
                    }
                }
            }
            return true;
        case 1:
            for(int i=0; i<p_iArr->cnt-1; i++)
            {
                for(int j=i+1; j<p_iArr->cnt; j++)
                {
                    if(p_iArr->pBase[i] < p_iArr->pBase[j])
                    {
                        temp = p_iArr->pBase[i];
                        p_iArr->pBase[i] = p_iArr->pBase[j];
                        p_iArr->pBase[j] = temp;
                    }
                }
            }
            return true;
        default:
            return false;  //order error
    }
}

/*
**  对数组中有效元素逆序.
**  @param p_iArr:管理整型数组的结构;
**  @ret   void
*/
void reverse_int_array(INT_ARRAY *p_iArr)
{
    int i=0, j=p_iArr->cnt-1;
    int t;
    while(i<j)
    {
        t = p_iArr->pBase[i];
        p_iArr->pBase[i] = p_iArr->pBase[j];
        p_iArr->pBase[j] = t;
        i++,j--;
    }
}

/*
**  对数组中有效元素进行查找.
**  @param p_iArr:管理整型数组的结构;
**  @param item:要查找的元素值;
**  @param iPos:元素的位置为第n个元素,n从1开始;
**  @ret   找到:true;未找到:false;
*/
bool search_int_array(INT_ARRAY *p_iArr, int item, int *iPos)
{
    for(int i=0; i<p_iArr->cnt; i++)
    {
        if(item == p_iArr->pBase[i])
        {
            *iPos = i+1;
            return true;
        }
    }
    return false;
}

/*
**  判满.
**  @param p_iArr:管理整型数组的结构;
**  @ret   已满:true;未满:false;
*/
bool int_array_isFull(INT_ARRAY *p_iArr)
{
    if(p_iArr->cnt >= p_iArr->length)
    {
        return true;
    }
    return false;
}

/*
**  判空.
**  @param p_iArr:管理整型数组的结构;
**  @ret   空:true;非空:false;
*/
bool int_array_isEmpty(INT_ARRAY *p_iArr)
{
    if(0 == p_iArr->cnt)
    {
        return true;
    }
    return false;
}

/*
**  位置有效性检测.
**  @param p_iArr:管理整型数组的结构;
**  @param iPos:要判定的位置;
**  @ret   有效:true;无效:false;
*/
bool valid_index(INT_ARRAY *p_iArr, int iPos)
{
    if(iPos<1 || iPos>p_iArr->cnt+1)
    {
        return false;
    }
    return true;
}
